package org.dicr.util.jds.conn.gui;

import java.util.*;

import javax.swing.*;

import org.dicr.event.*;
import org.dicr.util.jds.conn.*;

/***********************************************************************************************************************
 * Модель данных списка соединений.
 * 
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 030104
 **********************************************************************************************************************/
public class ConnectionsListModel extends AbstractListModel {
	private static final long serialVersionUID = 1L;

	private ConnectionsFactory factory = null;

	private Vector<Long> ids = new Vector<Long>();

	private FactoryListener factoryListener = new FactoryListener();

	/*******************************************************************************************************************
	 * Конструктор
	 ******************************************************************************************************************/
	public ConnectionsListModel() {
		super();
	}

	/*******************************************************************************************************************
	 * Обновляет модель
	 ******************************************************************************************************************/
	protected synchronized void updateModel() {
		try {
			this.ids = (this.factory != null) ? this.factory.getConnectionsID() : new Vector<Long>();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * Установка менеджера соединений
	 * 
	 * @param newFactory connection factory
	 ******************************************************************************************************************/
	public void setFactory(ConnectionsFactory newFactory) {
		if (this.factory != newFactory) try {
			if (this.factory != null) this.factory.removeProgramListener(this.factoryListener);
			int size = this.ids.size();
			if (size > 0) {
				this.ids.removeAllElements();
				fireIntervalRemoved(this, 0, size - 1);
			}
			this.factory = newFactory;
			if (this.factory != null) this.factory.addProgramListener(this.factoryListener);
		} finally {
			updateModel();
			int size = this.ids.size();
			if (size > 0) fireIntervalAdded(this, 0, size - 1);
		}
	}

	/*******************************************************************************************************************
	 * Возвращает менеджер соединений
	 * 
	 * @return connection factory
	 ******************************************************************************************************************/
	public ConnectionsFactory getFactory() {
		return this.factory;
	}

	/*******************************************************************************************************************
	 * Возвращает размер списка
	 * 
	 * @return size of list
	 ******************************************************************************************************************/
	@Override
    public int getSize() {
		return this.ids.size();
	}

	/*******************************************************************************************************************
	 * Возвращает элемент списка
	 * 
	 * @param index index of element
	 * @return element
	 ******************************************************************************************************************/
	@Override
    public Object getElementAt(int index) {
		Object elem = null;
		try {
			if (this.factory != null && index >= 0 && index < this.ids.size()) elem = this.factory.getConnection((this.ids.get(index)).longValue());
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
		return elem;
	}

	/*******************************************************************************************************************
	 * Слушатель менеджера соединений
	 ******************************************************************************************************************/
	class FactoryListener implements ProgramListener {
		/**
		 * @see org.dicr.event.ProgramListener#eventPerformed(org.dicr.event.ProgramEvent)
		 */
		@Override
        @SuppressWarnings("synthetic-access")
		public void eventPerformed(ProgramEvent e) {
			if (ConnectionsListModel.this.factory != null) try {
				Long conn = (Long) e.getParam();
				int index = -1;
				switch (e.getID()) {
					case ConnectionsFactory.EVENT_CONNECTION_ADDED:
						updateModel();
						index = ConnectionsListModel.this.ids.indexOf(conn);
						if (index != -1) fireIntervalAdded(ConnectionsListModel.this, index, index);
						else fireContentsChanged(ConnectionsListModel.this, 0, 0);
						break;
					case ConnectionsFactory.EVENT_CONNECTION_REMOVED:
						index = ConnectionsListModel.this.ids.indexOf(conn);
						updateModel();
						if (index != -1) fireIntervalRemoved(ConnectionsListModel.this, index, index);
						else fireContentsChanged(ConnectionsListModel.this, 0, 0);
						break;
					default:
						fireContentsChanged(ConnectionsListModel.this, 0, 0);
				}
			} catch (Exception ex) {
				DicrExceptionHandler.handleException(ex, this);
			}
		}
	}
}
